package org.springframework.social.connect.support;

import org.springframework.social.connect.ApiAdapter;
import org.springframework.social.connect.ConnectionData;
import org.springframework.social.oauth1.OAuth1ServiceProvider;

public class OAuth1Connection<A> extends AbstractConnection<A> {
  private static final long serialVersionUID = -808097401993144389L;
  
  private final transient OAuth1ServiceProvider<A> serviceProvider;
  
  private String accessToken;
  
  private String secret;
  
  private transient A api;
  
  public OAuth1Connection(String providerId, String providerUserId, String accessToken, String secret, OAuth1ServiceProvider<A> serviceProvider, ApiAdapter<A> apiAdapter) {
    super(apiAdapter);
    this.serviceProvider = serviceProvider;
    initAccessTokens(accessToken, secret);
    initApi();
    initKey(providerId, providerUserId);
  }
  
  public OAuth1Connection(ConnectionData data, OAuth1ServiceProvider<A> serviceProvider, ApiAdapter<A> apiAdapter) {
    super(data, apiAdapter);
    this.serviceProvider = serviceProvider;
    initAccessTokens(data.getAccessToken(), data.getSecret());
    initApi();
  }
  
  @Override
  public A getApi() {
    return this.api;
  }
  
  @Override
  public ConnectionData createData() {
    synchronized (getMonitor()) {
      return new ConnectionData(getKey().getProviderId(), getKey().getProviderUserId(), getDisplayName(), getProfileUrl(), getImageUrl(), this.accessToken, this.secret, null, null, getProviderUnionId());
    } 
  }
  
  private void initAccessTokens(String accessToken, String secret) {
    this.accessToken = accessToken;
    this.secret = secret;
  }
  
  private void initApi() {
    this.api = (A)this.serviceProvider.getApi(this.accessToken, this.secret);
  }
  
  @Override
  public int hashCode() {
    int prime = 31;
    int result = super.hashCode();
    result = 31 * result + ((this.accessToken == null) ? 0 : this.accessToken.hashCode());
    result = 31 * result + ((this.secret == null) ? 0 : this.secret.hashCode());
    return result;
  }
  
  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true; 
    if (!super.equals(obj))
      return false; 
    if (getClass() != obj.getClass())
      return false; 
    OAuth1Connection other = (OAuth1Connection)obj;
    if (this.accessToken == null) {
      if (other.accessToken != null)
        return false; 
    } else if (!this.accessToken.equals(other.accessToken)) {
      return false;
    } 
    if (this.secret == null) {
      if (other.secret != null)
        return false; 
    } else if (!this.secret.equals(other.secret)) {
      return false;
    } 
    return true;
  }
}
